/*
	Compresor Gzip
    Copyright (C) 2012 Darío López Padial 
    @bukosabino

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>
*/

/**
 	@file vectorbits.h
 	@brief Especificación de la clase VB
 	@author Dario Lopez Padial
*/

#ifndef _vector_bits_H_
#define _vector_bits_H_

#include <iostream>
#include "vectordinamico.h"

/**
@class VB
@brief El tipo de dato VB (VectorBits) nos da la opción de gestionar secuencas de bits, de forma dinámica.
Podremos hacer consultas, añadir bits, bytes, o vectores de bits, hacer comparaciones, 
asignaciones o inversiones de vectores de bits.
*/
class VB {

	private:

		VD _vector_char;
		unsigned int _num_bits;
		void Resize (int n);

	public:

		/**
		@brief	Constructor por defecto.
		*/
		VB () {
			_num_bits = 0;
		}

		/**
		@brief		Constructor primitivo con dos parámetros de entrada.
		@param n:	Valor numérico que queremos convertir a binario.
		@param m:	Número de bits con los que vamos a representar en binario el símbolo.
					Transformará un entero n, en su equivalente binario, con m bits.
		*/
		VB (unsigned long n, int m);

		/**
		@brief:	Destructor.
		*/
		~VB () {};

		/**
		@brief:	Devuelve el número de elementos (bits) que contiene el vector.
		*/
		int Size () const {
			return _num_bits;
		}

		/**
		@brief:	Invierte las posiciones de un vector de bits. 
		*/
		void Invertir ();

		/**
		@brief:		Escribe en un flujo de salida, el vector de bits en su forma comprimida.
		@param os:	Flujo de salida, en el que se escribe el vector de bits.
		*/
		void Escribir (std::ostream & os);

		/**
		@brief:				Modifica el bit de la posición i-ésima a un valor determinado.
		@param posicion:	Posición del vector de bits a modificar.
		@param dato:		Determina el valor del bit modificado.
		*/
		void Set (int posicion, bool dato);

		/**
		@brief:				Consulta el valor del bit en la posición parametrizada.
		@param posicion:	Posición del vector de bit a consultar.
		*/ 
		bool operator [] (unsigned int posicion) const;

		/**
		@brief: 		Añade un bit a nuestro vector de bits.
		@param dato:	Valor booleano del dato entrante.
		*/
		void operator += (bool dato);

		/**
		@brief:				Concatena 2 vectores dinámicos de bits.
		@param vector_aux:	Vector de bits entrante.
							Concatena un vector de bits entrante a uno ya implícito.
		*/
		void operator += (VB & vector_aux);

		/**
		@brief:			Añade un byte a nuestro vector de bits.
		@param byte:	Caracter entrante.
		*/
		void operator += (unsigned char byte);

		/**
		@brief: 			Compara la igualdad un vector de bits entrante con el vector implícito.
		@param vector_aux: 	Vector de bits entrante.
		*/
		bool operator == (VB & vector_aux);

		/**
		@brief: 			Compara la desigualdad entre un vector de bits entrante con el vector implícito.		
		@param vector_aux: 	Vector de bits entrante.
		*/
		bool operator != (VB & vector_aux);

		/**
		@brief:				Operador de asignación.
		@param vector_aux:	Es el vector "emisor" en la asignación.
							Para asignar vectores de bits entre sí.
		*/
		VB & operator = (const VB & vector_aux);

};

/**
@brief: Entrada de un flujo de bits por cin.
*/
std::istream & operator >> (std::istream & is, VB & vector_aux );
/**
@brief: Salida de un flujo de bits por cout.
*/
std::ostream & operator << (std::ostream & os, const VB & vector_aux );

#endif
